﻿// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
// -----------------------------------------------------------------------
using System;
using Microsoft.Internal;
using Microsoft.Internal.Collections;

namespace System.ComponentModel.Composition.ReflectionModel
{
    // Describes the import type of a Reflection-based import definition
    internal class ImportType
    {
        private readonly Type _type;
        private readonly Type _elementType;
        private readonly SpecializedExportType _lazyType;

        public ImportType(Type type)
        {
            Assumes.NotNull(type);

            _type = type;
            _elementType = GetEnumerableElementType(type);
            _lazyType = MakeSpecializedExportType(_type, _elementType);
        }

        public bool IsEnumerable
        {
            get { return _elementType != null; }
        }

        public bool IsLazy
        {
            get { return _lazyType != null; }
        }

        public Type ElementType
        {
            get { return _elementType; }
        }

        public Type Type
        {
            get { return _type; }
        }

        public SpecializedExportType LazyType
        {
            get { return _lazyType; }
        }

        private static SpecializedExportType MakeSpecializedExportType(Type type, Type elementType)
        {
            if (elementType == null)
            {
                // Create an Export<T, TMetadataView>-based export
                return SpecializedExportType.MakeExportType(type);
            }

            // Create an ExportCollection<T, TMetadataView>-based export
            return SpecializedExportType.MakeExportCollectionType(elementType);
        }


        public static Type GetEnumerableElementType(Type type)
        {
            Type elementType;
            if (CollectionServices.IsEnumerableType(type, out elementType))
            {
                return elementType;
            }

            return null;
        }
    }
}
